home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993…ch: Other People's Memory / ADC Developer CD (1993-03) (''Other People's Memory'')_iso / Dev.CD Mar 93.iso / Technical Documentation / Sample Code / DTS.Lib & Samples / DTS.Lib / StringUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-22  |  10.4 KB  |  531 lines  |  [TEXT/MPS ]

  1. /*
  2. **    Apple Macintosh Developer Technical Support
  3. **
  4. **    Collection of String Utilities for DTS Sample code
  5. **
  6. **    Program:    StringUtils.c.o
  7. **    File:        StringUtils.c
  8. **
  9. **    Copyright © 1988-1992 Apple Computer, Inc.
  10. **    All rights reserved.
  11. */
  12.  
  13.  
  14. #ifndef __MEMORY__
  15. #include <Memory.h>
  16. #endif
  17.  
  18. #ifndef __STRINGUTILS__
  19. #include "StringUtils.h"
  20. #endif
  21.  
  22.  
  23.  
  24. /* These functions should be linked into whatever segment holds main().  This will
  25. ** guarantee that the functions will always be in memory when called.  It is important
  26. ** that they are in memory, because if a pointer is passed in that points into an
  27. ** unlocked handle, the mere fact that the code needs to get loaded may cause the
  28. ** handle that is pointed into to move.  If you stick to these string functions,
  29. ** you will not have to worry about the handle moving when the string function is
  30. ** called.  If you have your own string functions, and you wish the same safety
  31. ** factor, link the string handling code into the same segment as main(), as you
  32. ** do with these string functions. */
  33.  
  34.  
  35.  
  36. /*****************************************************************************/
  37. /*****************************************************************************/
  38. /*****************************************************************************/
  39.  
  40.  
  41.  
  42. /* Return the length of the c-string.  (Same as strlen, but this function isn't
  43. ** part of the string library.  The entire library may be more than you wish to
  44. ** link into the code segment that holds main, so this (and other) standard
  45. ** library function has been duplicated here. */
  46.  
  47. #pragma segment StringUtils
  48. short    clen(char *cptr)
  49. {
  50.     short    i;
  51.  
  52.     for (i = 0; cptr[i]; ++i);
  53.     return(i);
  54. }
  55.  
  56.  
  57.  
  58. /*****************************************************************************/
  59.  
  60.  
  61.  
  62. /* Catenate two c-strings. */
  63.  
  64. #pragma segment StringUtils
  65. char    *ccat(char *s1, char *s2)
  66. {
  67.     ccpy(s1 + clen(s1), s2);
  68.     return(s1);
  69. }
  70.  
  71.  
  72.  
  73. /*****************************************************************************/
  74.  
  75.  
  76.  
  77. /* Copy a c-string. */
  78.  
  79. #pragma segment StringUtils
  80. char    *ccpy(char *s1, char *s2)
  81. {
  82.     char    *c1, *c2;
  83.  
  84.     c1 = s1;
  85.     c2 = s2;
  86.     while (*c1++ = *c2++);
  87.     return(s1);
  88. }
  89.  
  90.  
  91.  
  92. /*****************************************************************************/
  93.  
  94.  
  95.  
  96. /* Catenate two pascal-strings. */
  97.  
  98. #pragma segment StringUtils
  99. void    pcat(StringPtr d, StringPtr s)
  100. {
  101.     short    i, j;
  102.  
  103.     if (((j = s[0]) + d[0]) > 255)
  104.         j = 255 - d[0];
  105.             /* Limit dest string to 255. */
  106.  
  107.     for (i = 0; i < j;) d[++d[0]] = s[++i];
  108. }
  109.  
  110.  
  111.  
  112. /*****************************************************************************/
  113.  
  114.  
  115.  
  116. /* Copy a pascal-string. */
  117.  
  118. #pragma segment StringUtils
  119. void    pcpy(StringPtr d, StringPtr s)
  120. {
  121.     short    i;
  122.  
  123.     i = *s;
  124.     do {
  125.         d[i] = s[i];
  126.     } while (i--);
  127. }
  128.  
  129.  
  130.  
  131. /*****************************************************************************/
  132.  
  133.  
  134.  
  135. /* Convert a c-string to a pascal-string. */
  136.  
  137. #pragma segment StringUtils
  138. void    c2p(char *cptr)
  139. {
  140.     char    len;
  141.  
  142.     BlockMove(cptr, cptr + 1, len = clen(cptr));
  143.     *cptr = len;
  144. }
  145.  
  146.  
  147.  
  148. /*****************************************************************************/
  149.  
  150.  
  151.  
  152. /* Convert a pascal-string to a c-string. */
  153.  
  154. #pragma segment StringUtils
  155. void    p2c(StringPtr cptr)
  156. {
  157.     char    len;
  158.  
  159.     BlockMove(cptr + 1, cptr, len = *cptr);
  160.     cptr[len] = 0;
  161. }
  162.  
  163.  
  164.  
  165. /*****************************************************************************/
  166. /*****************************************************************************/
  167. /*****************************************************************************/
  168.  
  169.  
  170.  
  171. /* Catenate a single character multiple times onto the designated string. */
  172.  
  173. #pragma segment StringUtils
  174. void    ccatchr(char *cptr, char c, short count)
  175. {
  176.     ccpychr(cptr + clen(cptr), c, count);
  177. }
  178.  
  179.  
  180.  
  181. /*****************************************************************************/
  182.  
  183.  
  184.  
  185. /* Convert the value into text for the base-10 number and catenate it to
  186. ** the designated string.  The value is assumed to be signed.  If you wish
  187. ** to have an unsigned decimal value, call ccatnum with a base of 10. */
  188.  
  189. #pragma segment StringUtils
  190. void    ccatdec(char *cptr, long v)
  191. {
  192.     ccatnum(cptr + clen(cptr), v, -10);        /* Catenate value base 10, signed. */
  193. }
  194.  
  195.  
  196.  
  197. /*****************************************************************************/
  198.  
  199.  
  200.  
  201. /* Convert the value into text for base-16, format it, and catenate it to the
  202. ** designated string.  ccatnum could be used, since it handles multiple bases,
  203. ** but ccathex allows for additional common formatting and padding of the
  204. ** hex value. */
  205.  
  206. #pragma segment StringUtils
  207. void    ccathex(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  208. {
  209.     char    str[33], *sptr;
  210.     short    len;
  211.  
  212.     cptr += clen(cptr);            /* We're appending, so point to the end of the string. */
  213.     ccpynum(str, v, 16);        /* Generate minimum-digit hex value. */
  214.  
  215.     if ((len = clen(sptr = str)) > maxApnd)
  216.         sptr = str + len - maxApnd;
  217.  
  218.     if ((len = clen(sptr)) < minApnd)
  219.         if (padChr)
  220.             ccatchr(cptr, padChr, (minApnd - len));
  221.                 /* if we have a pad character, and if necessary, pad the string. */
  222.  
  223.     ccat(cptr, sptr);            /* Add the hex digits to the string. */
  224. }
  225.  
  226.  
  227.  
  228. /*****************************************************************************/
  229.  
  230.  
  231.  
  232. /* Convert the value into text for the designated base.  Catenate the text to
  233. ** the designated string. */
  234.  
  235. #pragma segment StringUtils
  236. void    ccatnum(char *cptr, long v, short base)
  237. {
  238.     ccpynum(cptr + clen(cptr), v, base);
  239. }
  240.  
  241.  
  242.  
  243. /*****************************************************************************/
  244.  
  245.  
  246.  
  247. #pragma segment StringUtils
  248. void    ccpychr(char *cptr, char c, short count)
  249. {
  250.     for (;count--; ++cptr) *cptr = c;
  251.     *cptr = 0;
  252. }
  253.  
  254.  
  255.  
  256. /*****************************************************************************/
  257.  
  258.  
  259.  
  260. #pragma segment StringUtils
  261. void    ccpydec(char *cptr, long v)
  262. {
  263.     ccpynum(cptr, v, -10);
  264. }
  265.  
  266.  
  267.  
  268. /*****************************************************************************/
  269.  
  270.  
  271.  
  272. #pragma segment StringUtils
  273. void    ccpyhex(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  274. {
  275.     cptr[0] = 0;
  276.     ccathex(cptr, padChr, minApnd, maxApnd, v);
  277. }
  278.  
  279.  
  280.  
  281. /*****************************************************************************/
  282.  
  283.  
  284.  
  285. #pragma segment StringUtils
  286. void    ccpynum(char *cptr, long v, short base)
  287. {
  288.     pcpynum((StringPtr)cptr, v, base);
  289.     p2c((StringPtr)cptr);
  290. }
  291.  
  292.  
  293.  
  294. /*****************************************************************************/
  295. /*****************************************************************************/
  296. /*****************************************************************************/
  297.  
  298.  
  299.  
  300. #pragma segment StringUtils
  301. long    c2dec(char *cptr, short *charsUsed)
  302. {
  303.     return(c2num(cptr, 10, charsUsed));
  304. }
  305.  
  306.  
  307.  
  308. /*****************************************************************************/
  309.  
  310.  
  311.  
  312. #pragma segment StringUtils
  313. long    c2hex(char *cptr, short *charsUsed)
  314. {
  315.     return(c2num(cptr, 16, charsUsed));
  316. }
  317.  
  318.  
  319.  
  320. /*****************************************************************************/
  321.  
  322.  
  323.  
  324. #pragma segment StringUtils
  325. long    c2num(char *cptr, short base, short *charsUsed)
  326. {
  327.     Boolean    firstDigit;
  328.     short    i;
  329.     short    c;
  330.     long    val;
  331.  
  332.     for (firstDigit = false, val = 0, i = 0;;) {
  333.         c = cptr[i++];
  334.         if ((!firstDigit) && ((c == ' ') || (c == '$'))) continue;
  335.         c -= '0';
  336.         if (c > 16) c -= 7;        /* Make 'A' a 10, etc. */
  337.         if (c > 32) c -= 32;    /* Make lower-case upper-case. */
  338.         if (c < 0) break;
  339.         if (c >= base) break;
  340.         val *= base;
  341.         val += c;
  342.         firstDigit = true;
  343.     }
  344.  
  345.     if (charsUsed) *charsUsed = --i;
  346.     return(val);
  347. }
  348.  
  349.  
  350.  
  351. /*****************************************************************************/
  352. /*****************************************************************************/
  353. /*****************************************************************************/
  354.  
  355.  
  356.  
  357. /*****************************************************************************/
  358.  
  359.  
  360.  
  361. /* Catenate a single character multiple times onto the designated string. */
  362.  
  363. #pragma segment StringUtils
  364. void    pcatchr(StringPtr pptr, char c, short count)
  365. {
  366.     while (count--) pptr[++(pptr[0])] = c;
  367. }
  368.  
  369.  
  370.  
  371. /*****************************************************************************/
  372.  
  373.  
  374.  
  375. #pragma segment StringUtils
  376. void    pcatdec(StringPtr pptr, long v)
  377. {
  378.     pcatnum(pptr, v, -10);
  379. }
  380.  
  381.  
  382.  
  383. /*****************************************************************************/
  384.  
  385.  
  386.  
  387. #pragma segment StringUtils
  388. void    pcathex(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  389. {
  390.     char    str[33];
  391.  
  392.     ccpyhex(str, padChr, minApnd, maxApnd, v);
  393.     c2p(str);
  394.     pcat(pptr, (StringPtr)str);
  395. }
  396.  
  397.  
  398.  
  399. /*****************************************************************************/
  400.  
  401.  
  402.  
  403. #pragma segment StringUtils
  404. long    pcatnum(StringPtr pptr, long v, short base)
  405. {
  406.     unsigned long    j, vv;
  407.  
  408.     vv = v;
  409.     if (base < 0) {
  410.         base = -base;
  411.         if (v < 0) {
  412.             pptr[++*pptr] = '-';
  413.             vv = -vv;
  414.         }
  415.     }
  416.     j = 0;
  417.     if (vv >= base)
  418.         j = pcatnum(pptr, vv / base, base);
  419.  
  420.     pptr[++*pptr] = "0123456789ABCDEF"[vv - j];
  421.     return(base * vv);
  422. }
  423.  
  424.  
  425.  
  426. /*****************************************************************************/
  427.  
  428.  
  429.  
  430. #pragma segment StringUtils
  431. void    pcpydec(StringPtr pptr, long v)
  432. {
  433.     *pptr = 0;
  434.     pcatdec(pptr, v);
  435. }
  436.  
  437.  
  438.  
  439. /*****************************************************************************/
  440.  
  441.  
  442.  
  443. #pragma segment StringUtils
  444. void    pcpynum(StringPtr pptr, long v, short base)
  445. {
  446.     *pptr = 0;
  447.     pcatnum(pptr, v, base);
  448. }
  449.  
  450.  
  451.  
  452. /*****************************************************************************/
  453.  
  454.  
  455.  
  456. #pragma segment StringUtils
  457. void    pcpyhex(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  458. {
  459.     *pptr = 0;
  460.     pcpyhex(pptr, padChr, minApnd, maxApnd, v);
  461. }
  462.  
  463.  
  464.  
  465. /*****************************************************************************/
  466.  
  467.  
  468.  
  469. #pragma segment StringUtils
  470. long    p2dec(StringPtr pptr, short *charsUsed)
  471. {
  472.     return(p2num(pptr, 10, charsUsed));
  473. }
  474.  
  475.  
  476.  
  477. /*****************************************************************************/
  478.  
  479.  
  480.  
  481. #pragma segment StringUtils
  482. long    p2hex(StringPtr pptr, short *charsUsed)
  483. {
  484.     return(p2num(pptr, 16, charsUsed));
  485. }
  486.  
  487.  
  488.  
  489. /*****************************************************************************/
  490.  
  491.  
  492.  
  493. #pragma segment StringUtils
  494. long    p2num(StringPtr pptr, short base, short *charsUsed)
  495. {
  496.     long    val;
  497.  
  498.     p2c(pptr);
  499.     val = c2num((char *)pptr, base, charsUsed);
  500.     c2p((char *)pptr);
  501.     return(val);
  502. }
  503.  
  504.  
  505.  
  506. /*****************************************************************************/
  507. /*****************************************************************************/
  508. /*****************************************************************************/
  509.  
  510.  
  511.  
  512. #pragma segment StringUtils
  513. short    GetHexByte(char *cptr)
  514. {
  515.     short    val, i, chr;
  516.  
  517.     for (val = 0, i = 0; i < 2; ++i) {
  518.         chr = cptr[i];
  519.         if (chr == '=') return(cptr[++i]);
  520.         if (chr > 'F')
  521.             chr -= 0x20;
  522.         if (chr > '9')
  523.             chr -= ('A' - '9' - 1);
  524.         val = (val << 4) + chr - '0';
  525.     }
  526.     return(val);
  527. }
  528.  
  529.  
  530.  
  531.